package org.bling.star.server;

import io.netty.channel.socket.ServerSocketChannel;
import org.bling.star.common.connection.IDbConnection;
import org.bling.star.server.adapter.impl.AdapterContextManager;
import org.bling.star.server.connect.ConnectInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.bling.star.server.connect.GlobalConnectManager;
import org.bling.star.server.connect.handlers.ConnectPing;
import org.bling.star.server.dispatchers.StrategyFactory;

/**
 * @Describe:
 * @Date: 2024/7/9
 * @Author: szz
 */
public class ServerApplication {

    public static void main(String[] args) {
        init();
        GlobalConnectManager connect = start("localhost", 9999,null);
        connect.syncListener();
    }

    /**
     *
     * @param host
     * @param port
     * @param strategyFactory 指令工厂，放入对应命令用于客户端调用对应指令
     * @return
     */
    public static GlobalConnectManager start(String host, int port, StrategyFactory strategyFactory) {
        try {
            NioEventLoopGroup bossGroup  = new NioEventLoopGroup();
            NioEventLoopGroup workGroup = new NioEventLoopGroup();
            ServerBootstrap serverBootstrap  = new ServerBootstrap();
            ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)  // 保持长连接
                    .childHandler(new ConnectInitializer("",strategyFactory))
                    .handler(new ChannelInitializer<ServerSocketChannel>() {
                        @Override
                        protected void initChannel(ServerSocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ConnectPing());
                        }
                    })
                    .bind(host, port).sync();
            Channel channel = channelFuture.channel();
            channel.closeFuture().addListener(future -> {
                if(future.isSuccess()) {
                    bossGroup.shutdownGracefully();
                    workGroup.shutdownGracefully();
                }
            });

            return new GlobalConnectManager(channel);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
        }
    }

    private static void init() {
        AdapterContextManager instance = AdapterContextManager.getInstance();
        IDbConnection adapter = instance.getAdapter(IDbConnection.class);
        String execute = adapter.execute("123");
        System.out.println(execute);
    }
}
